package com.gbase8c.dmt.db.opengauss;

import com.gbase8c.dmt.db.object.ViewObject;

import com.gbase8c.dmt.model.migration.config.Task;
import com.gbase8c.dmt.model.migration.dto.DataSourceDto;
import com.gbase8c.dmt.model.migration.dto.TableDto;
import com.gbase8c.dmt.model.migration.dto.ViewDto;
import com.google.common.collect.Lists;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ViewObjectImpl extends MetaImpl implements ViewObject {

    public ViewObjectImpl(DataSourceDto dataSourceDto) {
        super(dataSourceDto);
    }

    @Override
    public List<String> getNames(Map<String, Object> params) {
        List<String> names = Lists.newArrayList();
        return names;
    }

    @Override
    public ViewDto get(String name, Map<String, Object> params) {
        return null;
    }

    @Override
    public ViewDto convert(ViewDto viewDto, Map<String, Object> params) {
        Task task = viewDto.getTask();
        boolean preserveCase = task.getMigrateConfig().isPreserveCase();

        String gbase8cViewDefinition = null;
        Boolean convertible = Boolean.TRUE;
        String definition = viewDto.getSrcDefinition();
        if (StringUtils.isBlank(definition)){
            convertible = Boolean.FALSE;
        }
        gbase8cViewDefinition = definition;
        gbase8cViewDefinition = gbase8cViewDefinition.replaceAll("`", "");
        if (!preserveCase) {
            gbase8cViewDefinition = gbase8cViewDefinition.toLowerCase();
        }
        //oracle视图定义语句有'with check option'或者'with read only'。8c不支持，tarsql取最后一个with出现的位置，截掉后面内容
        if (gbase8cViewDefinition.contains("with")) {
            int lastIndex = gbase8cViewDefinition.lastIndexOf("with");
            gbase8cViewDefinition = gbase8cViewDefinition.substring(0,lastIndex);
        }
        if (gbase8cViewDefinition.contains("WITH")) {
            int lastIndex = gbase8cViewDefinition.lastIndexOf("WITH");
            gbase8cViewDefinition = gbase8cViewDefinition.substring(0,lastIndex);
        }
        viewDto.setTarDefinition(gbase8cViewDefinition);
        viewDto.setConvertible(convertible);
        viewDto.setConvertible(true);

        if(viewDto.getConvertible()){
            viewDto.setConvertMsg("已完成");
        } else {
            viewDto.setConvertMsg("失败");
        }

        List<TableDto.ColumnDto> columnDtos = viewDto.getColumnDtos();
        List<String> columns = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(columnDtos)){
            for (TableDto.ColumnDto columnDto:columnDtos){
                columns.add(columnDto.getName());
            }
        }
        viewDto.setColumns(String.join(",",columns));

        if (viewDto.getMsg() != null){
            viewDto.setNoteMsg(viewDto.getMsg());
        } else {
            viewDto.setNoteMsg("-");
        }
        return viewDto;
    }

    @Override
    public String sql(ViewDto viewDto, Map<String, Object> params) {
        //todo:根据viewDto生成视图创建SQL
        StringBuilder sb = new StringBuilder();
        String createViewSql = null;
        String tarSchemaName = viewDto.getTarSchema();
        // todo
        String viewName = viewDto.getName();
        boolean preserveCase = viewDto.getTask().getMigrateConfig().isPreserveCase();
        List<String> viewColumnList = viewDto.getColumnDtos().stream()
                .map(columnDto -> columnDto.getName())
                .collect(Collectors.toList());
        String viewColumns = StringUtils.join(viewColumnList,",");

        //此条命令定位到此schema下执行，解决建视图From语句后必须模式名.表名的情况
        sb.append("set search_path to ");
        sb.append(wrap(tarSchemaName, true));
        sb.append(";");

        sb.append("CREATE OR REPLACE VIEW ");
        sb.append(wrap(tarSchemaName, true)).append(".").append(wrap(viewName, preserveCase));
        sb.append("(").append(viewColumns).append(")");
        if (!StringUtils.isBlank(viewDto.getViewOptions())) {
            String viewOptions = viewDto.getViewOptions();
            sb.append(" with(").append(viewOptions).append(") ");
        }
        sb.append(" AS ").append(viewDto.getTarDefinition());
        createViewSql = sb.toString();
        return createViewSql;
    }
}
